home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Libris Britannia 4
/
science library(b).zip
/
science library(b)
/
PROGRAMM
/
ASSEMBLE
/
3809.ZIP
/
ASMLIB.ZIP
/
EMSXMS.DOC
< prev
next >
Wrap
Text File
|
1993-04-27
|
32KB
|
1,003 lines
******************** EXPANDED AND EXTENDED MEMORY **************************
ASMLIB's EMS subroutines detect and manipulate Expanded Memory hardware
and software. Expanded memory, when installed in any PC, can help solve
many memory limitation problems. Call IsEMS before using any other
ASMLIB EMS subroutines. All ASMLIB EMS subroutines assume DS:@data.
EMS memory is allocated in blocks of 16k increments
Error codes returned by EMS functions are:
AH = 0 no error
AH = 80h error in memory manager software
AH = 81h error in expanded memory hardware
AH = 84h bad function code passed to memory manager
AH = 85h no EMM handles available
AH = 89h you tried to allocate zero pages
ASMLIB also supports XMS-compatible extended memory. You must call IsXMS
to determine if XMS memory is available before using any ASMLIB XMS
subroutines. All ASMLIB XMS subroutines assume DS:@data.
XMS memory is available on many 286 or better computers with a suitable
driver. On 286 computers, XMS memory will be much slower than EMS memory.
XMS memory is not available on XT (or compatible) computers.
XMS memory is allocated in 1k increments
XMS error codes include:
AH = 0 no error
AH = 0A0h all extended memory is allocated
AH = 0A1h no handles available
AH = 0A2h, 0A3h, 0A5h handle is invalid
AH = 0A4h, 0A6h offset is invalid
AH = 0A7h length is invalid
ASMLIB includes disk-based Virtual Memory subroutines (VMS) which make
possible the use of disk space as though it were RAM. Error codes returned
by VMS subroutines are DOS error codes.
ASMLIB's EMS, VMS and XMS subroutines were written with identical calling
parameters and identical returned information for comparable subroutines.
For example, AllocEMS and AllocXMS are both called with DX:AX = the number
of bytes requested.
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
ALLOCEMS: allocates EMS memory
Source: ems.asm
Call with: DX:AX = number of bytes of memory to allocate
EMS memory is allocated in 16k blocks. AllocEMS will allocate
multiple blocks if nessesary.
NOTE: You must first use IsEMS to determine if Expanded
memory is installed.
Returns: if CF = 0, BX = EMS handle
if CF = 1, AH = EMS error code
Uses: AX, BX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
ALLOCVMS: allocates VMS memory
Source: allocvms.asm
Call with: DX:AX = bytes of VMS memory to allocate
DS:[SI] pointing to filename for VMS block
AllocVMS creates a file of the size requested, thus reserving
space on the disk for the memory block. The file should not
be presumed to contain useful data.
Returns: if CF = 0, BX = VMS handle
if CF = 1, AX = DOS error code
Uses: AX, BX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
ALLOCXMS: allocates XMS memory
Source: xms.asm
Call with: DX:AX = number of bytes of memory to allocate
XMS memory is allocated in 1k blocks. AllocXMS will allocate
multiple blocks if nessesary.
NOTE: You must first use IsXMS to determine if XMS Extended
memory is available.
Returns: if CF = 0, BX = XMS handle
if CF = 1, AH = XMS error code
Uses: AX, BX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
EMGET: copy data from EMS memory to system RAM
Source: emputget.asm ($emspage.asm)
Call with: BX = EMS handle
ES:[DI] pointing to destination buffer
DS:[SI] pointing to 4-byte offset in EMS block
DX:AX = number of bytes to copy
Returns: if CF = 0, no error
if CF = 1, AH = EMS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
EMMOVE: move data within an EMS memory block
this is used most often to make room for additional data
at a specified location in the EMS block, or to delete data
from the block.
Source: emmove.asm (xget$.asm, $xmove.asm, emputget.asm, $emspage.asm)
Call with: BX = valid EMS handle
DS:[SI] pointing to source offset in EMS block
DS:[DI] pointing to destination offset in EMS block
DX:AX = number of bytes to move
64k DOS memory must be available; assumes DS:@data
EMMove works properly if the source and destination
overlap; you must make sure the EMS block is large enough
to accomodate the move.
Returns: if CF = 0, no error
if CF = 1, AH = DOS or EMS error code
the only DOS error code likely is 08h, insufficient memory
Uses: AX, flags
Example:
; calculate bytes to move
mov ax,block_size
mov dx,block_size ; DX:AX = bytes in expanded memory block
sub ax,source
sbb dx,source+2 ; DX:AX = bytes in tail end of block
; = bytes to move
mov bx,block_handle
lea si,source
lea di,destination
call emmove
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
EMMVER: determines Expanded Memory Manager version
Source: emmver.asm
Call with: no parameters
Returns: if CF = 1, AH = EMS error code
if CF = 0, AH = major version number
AL = minor version number
Uses: AX, flags
Example:
include asm.inc
extrn isems:proc, emmver:proc
.code
.
.
.
call isems
jc no_ems
call emmver ; get emm version
jc ems_error
cmp ah,4 ; version 4.x?
jb version3x ; nope, an older EMM version
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
EMPUT: copy data to EMS memory from system RAM
Source: emputget.asm ($emspage.asm)
Call with: BX = EMS handle
ES:[DI] pointing to data to copy
DS:[SI] pointing to 4-byte offset in EMS block
DX:AX = number of bytes to copy
Returns: if CF = 0, no error
if CF = 1, AH = EMS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
EMSFREE: determine free EMS memory
Source: emsfree.asm
Call with: no parameters
EMSFree does not verify that EMS memory is installed; you should
call IsEMS to determine if EMS memory is installed before using
this subroutine. Do not confuse this subroutine with FreeEMS,
which releases a previously allocated EMS block and handle.
Returns: DX:AX = bytes of EMS memory available
Uses: AX, DX, flags
Example:
include asm.inc
public myprog
extrn isems:proc, emsfree:proc
.code
myprog proc
call isems ; see if EMS memory is installed
jc nope
call emsfree ; is enough available?
.
.
.
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
EMSTOTAL: determine total EMS memory installed
Source: emsfree.asm
Call with: no parameters; call IsEMS to determine if EMS memory is
installed before using this subroutine
Returns: DX:AX = bytes of EMS memory installed
Uses: AX, DX, flags
Example:
include asm.inc
public myprog
extrn isems:proc, emstotal:proc
.code
myprog proc
call isems ; see if EMS memory is installed
jc nope
call emstotal ; how much?
.
.
.
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
EMISTR: search expanded memory block for ASCIIZ string, case-insensitive
Source: emistr.asm (xget$.asm, $xistr.asm, emputget.asm, strlen.asm,
$strstr.asm, strlwr.asm)
EMSTR: search expanded memory block for ASCIIZ string, case-sensitive
Source: emstr.asm (xget$.asm, $xstr.asm, emputget.asm, $strstr.asm,
strlen.asm)
Call with: DS:[SI] pointing to ASCIIZ string
BX = valid EMS handle
DS:[DI] pointing to 4-byte initial offset for start of search
DX:AX = number of bytes of EMS block to search
requires 64k free DOS memory (see ENDPROG and STARTUP.ASM)
Returns: if CF = 0, DX:AX = offset of matching string in EMS block
if CF = 1:
if AX = 0, string not found
else AH = EMS error code
Uses: DX,AX, flags
Example:
include asm.inc
public mycode
extrn emstr:proc
.data
extrn ems_handle:word
extrn ems_bytes:word ; 2 words
ems_offset dw 0,0 ; start at beginnig of block
search_string db 'ASMLIB',0
.code
mycode proc
; program fragment assumes EMS memory has been allocated
; and has useful data
.
.
lea si,search_string
mov bx,ems_handle
mov ax,ems_bytes
mov dx,ems_bytes+2 ; DX:AX = bytes to search
lea di,ems_offset ; start search at beginning of XMS block
call emstr ; returns DX:AX = offset of 'ASMLIB'
jnc found_it
or ax,ax
jz no_match ; no errors, but no match either
jmp oh_no_an_error ; jump to error handling code
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FLOADEMS: reads a disk file and copies to EMS memory
Source: floadems.asm (fsize.asm, ems.asm)
Call with: DS:[DX] pointing to ASCIIZ filename
call IsEMS before calling FLoadEMS to determine if EMS memory
is available
Returns: if CF = 0, BX = EMS handle and DX:AX = bytes copied to EMS
if CF = 1, AH = EMS error code or AL = DOS error code
Uses: AX, BX, DX, CF
Example:
include asm.inc
public test_ems
extrn isems:proc
extrn gsave:proc, floadems:proc
.data
handle dw 0
fname db 'filename.12h',0
.code
test_ems proc
; program fragment assumes DS:@data
mov ax,12h ; VGA 16-color mode
int 10h ; set mode
. ; program draws screen
.
; I want to save this screen as a disk file
call isems
jc no_good
lea dx,fname
call gsave ; GSave is in GRAPHICS.DOC
jc no_good
.
.
; now I want to get back the screen I saved
lea dx,fname
call floadems ; read file, load into EMS memory
mov handle,bx
jc no_good
call gloadems ; copy from EMS memory to video buffer
jc kill_ems
call getkey ; now look at the pretty picture
kill_ems:
mov dx,handle
mov ah,45h
int 67h
no_good:call modecolor ; go back to color text mode
ret
test_ems endp
end
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FLOADVMS: reads a disk file and copies to VMS memory
Source: floadvms.asm (fcopy.asm, fsize.asm)
Call with: DS:[DX] pointing to input ASCIIZ filename
DS:[SI] pointing to VMS filename
The VMS filename is the name of the file created as VMS memory
64k DOS memory must be available for FLoadVMS' use
Returns: if CF = 0, BX = VMS handle and DX:AX = bytes copied
if CF = 1, AX = DOS error code
Uses: AX, BX, DX, flags
Example: see FLoadEMS example
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FLOADXMS: reads a disk file and copies to XMS memory
Source: floadxms.asm (fsize.asm, xmputget.asm, xms.asm)
Call with: DS:[DX] pointing to ASCIIZ filename
call IsXMS before calling FLoadXMS to determine if XMS memory
is available
64k DOS memory must be available for FLoadXMS' use
Returns: if CF = 0, BX = XMS handle and DX:AX = bytes copied to XMS
if CF = 1, AH = XMS error code or AL = DOS error code
Uses: AX, BX, DX, CF
Example: see FLoadEMS example
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FSAVEEMS: writes an EMS memory block to disk file
Source: fsaveems.asm ($fsavex.asm, emputget.asm)
Call with: DS:[SI] pointing to ASCIIZ filename
BX = valid EMS handle
DX:AX = bytes to write
64k DOS memory must be available for FSaveEMS' use
Returns: if CF = 0, no error
if CF = 1, AH = EMS error code or AL = DOS error code
Uses: AX, flags
Example:
.data
emsfile db 'bigblock.ems',0
emssize dd ? ; program fills in the numbers
emshandle dw ? ; program fills in the numbers
.code
swap_ems_to_disk proc
; program fragment assumes DS:@data
lea si,emsfile ; filename
mov bx,emshandle
mov ax,word ptr emssize
mov dx,word ptr emssize+2 ; DX:AX = bytes to save
call fsaveems ; save EMS block as disk file
jc no_good
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FSAVEVMS: save a VMS memory block as a disk file
Source: fsavevms.asm (xget$.asm, $fsavex.asm, vmputget.asm)
Call with: DS:[SI] pointing to ASCIIZ filename
BX = valid VMS handle
DX:AX = bytes to write
64k DOS memory must be available for FSaveVMS' use
Returns: if CF = 0, no error
if CF = 1, AX = DOS error code
Uses: AX, flags
Example: see FSaveEMS example
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FSAVEXMS: writes an XMS memory block to disk file
Source: fsavexms.asm (xget$.asm, $fsavex.asm, xms.asm, xmputget.asm)
Call with: DS:[SI] pointing to ASCIIZ filename
BX = valid XMS handle
DX:AX = bytes to write
64k DOS memory must be available for FSaveXMS' use
Returns: if CF = 0, no error
if CF = 1, AH = XMS error code or AL = DOS error code
Uses: AX, flags
Example: see FSaveEMS example
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FREEEMS: releases an EMS memory block and handle
Source: ems.asm
Call with: BX = EMS handle
NOTE: DOS does not release EMS memory when your program
returns to DOS. Your program must close any open EMS handles
before quitting, or the EMS memory associated with the handles
will be unavailable to other programs. Do not confuse this
subroutine with EMSFree, whick determines the EMS memory
available.
Returns: if CF = 0, no error
if CF = 1, AH = EMS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FREEVMS: releases a VMS memory block and handle
Source: freevms.asm
Call with: BX = VMS handle
DS:[SI] pointing to VMS block filename
Returns: if CF = 0, no error
if CF = 1, AX = DOS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
FREEXMS: releases an XMS memory block and handle
Source: xms.asm
Call with: BX = XMS handle
NOTE: DOS does not release XMS memory when your program ends.
Your program must close any open XMS handles before quitting,
or the XMS memory associated with the handles will be
unavailable to other programs. Do not confuse this subroutine
with XMSFree, whick determines the XMS memory available.
Returns: if CF = 0, no error
if CF = 1, AH = XMS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
ISEMS: detects EMS driver
Source: isems.asm
Call with: no parameters
Returns: if CF = 1, no Expanded Memory manager installed
if CF = 0, EMS memory is installed
Uses: CF
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
ISXMS: detects XMS driver
Source: isxms.asm
Call with: no parameters
Returns: if CF = 1, no XMS driver is installed
if CF = 0, XMS memory is available
Uses: CF
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
REALLOCEMS: re-size a previously allocated EMS memory block
Source: realloce.asm
Call with: BX = valid EMS memory handle
DX:AX = requested bytes
Returns: if CF = 0, no error
if CF = 1, AH = EMS error code
Supports: EMS version 4.0 or greater (see EMMVER)
Uses: AX, flags
Example:
mov bx,emshandle ; existing valid EMS handle
mov ax,bytes
mov dx,bytes+2 ; DX:AX = bytes requested
call reallocems ; try to re-size existing block
jc alloc_error
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
REALLOCVMS: re-size a previously allocated VMS memory block
Source: reallocv.asm
Call with: BX = valid VMS memory handle
DX:AX = requested bytes
Note that ReallocVMS can only make the VMS block larger
if a smaller VMS block is requested, ReallocVMS does nothing
and returns with CF = 0
Returns: if CF = 0, no error
if CF = 1, AX = DOS error code
Uses: AX, flags
Example:
mov bx,vmshandle ; existing valid VMS handle
mov ax,bytes
mov dx,bytes+2 ; DX:AX = bytes requested
call reallocvms ; try to re-size existing block
jc alloc_error
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
REALLOCXMS: re-size a previously allocated XMS memory block
Source: reallocx.asm (xms.asm)
Call with: BX = valid XMS memory handle
DX:AX = requested bytes
Returns: if CF = 0, no error
if CF = 1, AH = XMS error code
Uses: AX, flags
Example:
mov bx,xmshandle ; existing valid XMS handle
mov ax,bytes
mov dx,bytes+2 ; DX:AX = bytes requested
call reallocxms ; try to re-size existing block
jc alloc_error
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
VMGET: copy data from VMS memory to system RAM
Source: vmputget.asm
Call with: BX = VMS handle
ES:[DI] pointing to destination buffer
DS:[SI] pointing to 4-byte offset in VMS block
DX:AX = number of bytes to copy
Returns: if CF = 0, no error
if CF = 1, AX = DOS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
VMMOVE: move data within a VMS memory block
Source: vmmove.asm (xget$.asm, $xmove.asm, vmputget.asm)
Call with: BX = valid VMS handle
DS:[SI] pointing to source offset in VMS block
DS:[DI] pointing to destination offset in VMS block
DX:AX = number of bytes to move
64k DOS memory must be available; assumes DS:@data
VMMove works properly if the source and destination
overlap; you must make sure the block is large enough
to accomodate the move.
Returns: if CF = 0, no error
if CF = 1, AX = DOS error code
Uses: AX, flags
Example:
; calculate bytes to move
mov ax,block_size
mov dx,block_size ; DX:AX = bytes in extended memory block
sub ax,source
sbb dx,source+2 ; DX:AX = bytes in tail end of block
; = bytes to move
mov bx,block_handle
lea si,source
lea di,destination
call vmmove
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
VMPUT: copy data to VMS memory from system RAM
Source: vmputget.asm
Call with: BX = VMS handle
ES:[DI] pointing to data to copy
DS:[SI] pointing to 4-byte offset in VMS block
DX:AX = number of bytes to copy
Returns: if CF = 0, no error
if CF = 1, AX = VMS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
VMISTR: search VMS memory block for ASCIIZ string, case-insensitive
Source: vmistr.asm (xget$.asm, $xistr.asm, vmputget.asm, strlen.asm,
strlwr.asm)
VMSTR: search VMS memory block for ASCIIZ string, case-sensitive
Source: vmstr.asm (xget$.asm, $xstr.asm, vmputget.asm, strlen.asm)
Call with: DS:[SI] pointing to ASCIIZ string
BX = valid VMS handle
DS:[DI] pointing to 4-byte initial offset for start of search
DX:AX = number of bytes of VMS block to search
requires 64k free DOS memory (see ENDPROG and STARTUP.ASM)
Returns: if CF = 0, DX:AX = offset of matching string in VMS block
if CF = 1:
if AX = 0, string not found
else AX = DOS error code
Uses: DX, AX, flags
Example:
include asm.inc
public mycode
extrn vmstr:proc
.data
extrn vms_handle:word
extrn vms_bytes:word ; 2 words
vms_offset dw 0,0 ; start at beginnig of block
search_string db 'ASMLIB',0
.code
mycode proc
; program fragment assumes VMS memory has been allocated
; and has useful data
.
.
lea si,search_string
mov bx,vms_handle
mov ax,vms_bytes
mov dx,vms_bytes+2 ; DX:AX = bytes to search
lea di,vms_offset ; start search at beginning of VMS block
call vmstr ; returns DX:AX = offset of 'ASMLIB'
jnc found_it
or ax,ax
jz no_match ; no errors, but no match either
jmp oh_no_an_error ; jump to error handling code
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
XMGET: copy data from XMS memory to system RAM
Source: xmputget.asm (xms.asm)
Call with: BX = XMS handle
ES:[DI] pointing to destination buffer
DS:[SI] pointing to 4-byte offset in XMS block
DX:AX = number of bytes to copy (minimum 2 bytes)
Returns: if CF = 0, no error
if CF = 1, AH = XMS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
XMMOVE: move data within an XMS memory block
Source: xmmove.asm (xget$.asm, $xmove.asm, xmputget.asm, xms.asm)
Call with: BX = valid XMS handle
DS:[SI] pointing to source offset in XMS block
DS:[DI] pointing to destination offset in XMS block
DX:AX = number of bytes to move (minimum 2 bytes)
64k DOS memory must be available; assumes DS:@data
XMMove works properly if the source and destination
overlap; you must make sure the block is large enough
to accomodate the move.
Returns: if CF = 0, no error
if CF = 1, AH = DOS or XMS error code
the only DOS error code likely is 08h, insufficient memory
Uses: AX, flags
Example:
; calculate bytes to move
mov ax,block_size
mov dx,block_size ; DX:AX = bytes in extended memory block
sub ax,source
sbb dx,source+2 ; DX:AX = bytes in tail end of block
; = bytes to move
mov bx,block_handle
lea si,source
lea di,destination
call xmmove
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
XMPUT: copy data to XMS memory from system RAM
Source: xmputget.asm (xms.asm)
Call with: BX = XMS handle
ES:[DI] pointing to data to copy
DS:[SI] pointing to 4-byte offset in XMS block
DX:AX = number of bytes to copy (minimum 2 bytes)
Returns: if CF = 0, no error
if CF = 1, AH = XMS error code
Uses: AX, flags
Example: see example code at the end of this file
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
XMSFREE: determine free XMS memory
Source: xmsfree.asm
Call with: no parameters
XMSFree does not verify that XMS memory is installed; you should
call IsXMS to determine if XMS memory is installed before using
this subroutine. Do not confuse this subroutine with FreeXMS,
which releases a previously allocated XMS block and handle.
Returns: DX:AX = bytes of XMS memory available
Uses: AX, DX, flags
Example:
include asm.inc
public myprog
extrn isxms:proc, xmsfree:proc
.code
myprog proc
call isxms ; see if XMS memory is installed
jc nope
call xmsfree ; is enough available?
.
.
.
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
XMISTR: search extended memory block for ASCIIZ string, case-insensitive
Source: xmistr.asm (xget$.asm, $xistr.asm, xmputget.asm, strlen.asm,
strlwr.asm)
XMSTR: search extended memory block for ASCIIZ string, case-sensitive
Source: xmstr.asm (xget$.asm, $xstr.asm, xmputget.asm, strlen.asm)
Call with: DS:[SI] pointing to ASCIIZ string
BX = valid XMS handle
DS:[DI] pointing to 4-byte initial offset for start of search
DX:AX = number of bytes of XMS block to search
requires 64k free DOS memory (see ENDPROG and STARTUP.ASM)
Returns: if CF = 0, DX:AX = offset of matching string in XMS block
if CF = 1:
if AX = 0, string not found
else AH = XMS error code
Uses: DX,AX, flags
Example:
include asm.inc
public mycode
extrn xmstr:proc
.data
extrn xms_handle:word
extrn xms_bytes:word ; 2 words
xms_offset dw 0,0 ; start at beginnig of block
search_string db 'ASMLIB',0
.code
mycode proc
; program fragment assumes XMS memory has been allocated
; and has useful data
.
.
lea si,search_string
mov bx,xms_handle
mov ax,xms_bytes
mov dx,xms_bytes+2 ; DX:AX = bytes to search
lea di,xms_offset ; start search at beginning of XMS block
call xmstr ; returns DX:AX = offset of 'ASMLIB'
jnc found_it
or ax,ax
jz no_match ; no errors, but no match either
jmp oh_no_an_error ; jump to error handling code
; EXPANDED AND EXTENDED MEMORY EXAMPLE CODE
; This example determines if EMS or XMS memory is installed, allocates
; 32k of EMS or XMS memory, copies a Herules graph to the allocated memory
; and later, copies the data back to the video buffer and releases
; the memory block
include asm.inc
public herc2x
extrn isems:proc, isxms:proc
extrn allocems:proc, allocxms:proc
extrn emput:proc, xmput:proc
extrn emget:proc, xmget:proc
extrn freeems:proc, freexms:proc
.data
IF @codesize
xalloc dd 0
xput dd 0
xget dd 0
xfree dd 0
ELSE
xalloc dw 0
xput dw 0
xget dw 0
xfree dw 0
ENDIF
xoffset dw 0,0
xhandle dw 0
xerror dw 0
.code
herc2x proc
; program fragment assumes DS:@data
; set up default conditions: use EMS
mov xerror,offset ems_error
mov word ptr xalloc,offset allocems
mov word ptr xput,offset emput
mov word ptr xget,offset emget
mov word ptr xfree,offset freeems
IF @codesize
mov ax,seg allocems
mov word ptr xalloc+2,ax ; all ASMLIB code in same segment
mov word ptr xput+2,ax
mov word ptr xget+2,ax
mov word ptr xfree+2,ax
ENDIF
; see if EMS is installed
call isems
jnc allocate_memory
; EMS not installed - see if XMS memory is avaialble
; set up for XMS subroutines
mov xerror,offset xms_error
mov word ptr xalloc,offset allocxms
mov word ptr xput,offset xmput
mov word ptr xget,offset xmget
mov word ptr xfree,offset freexms
IF @codesize
mov ax,seg allocxms
mov word ptr xalloc+2,ax ; all ASMLIB code in same segment
mov word ptr xput+2,ax
mov word ptr xget+2,ax
mov word ptr xfree+2,ax
ENDIF
call isxms
jc foiled_again ; don't use EMS or XMS
; allocate 32k
allocate_memory:
mov ax,32768
xor dx,dx ; DX:AX = 32768
call xalloc ; allocate EMS or XMS memory block
jc xerror
mov xhandle,bx ; save the handle
; copy the graph to EMS or XMS
mov di,0B000h ; Hercules buffer
mov es,di
xor di,di ; ES:[DI] -> video buffer
mov ax,32768 ; copy entire graph
lea si,xoffset ; start at offset 0 in memory block
call xput ; copy the graph to memory
jc xerror
; later ...
; copy the graph back to the video buffer
mov bx,xhandle
mov dx,0B000h
mov es,dx
xor di,di ; ES:[DI] points to destination
mov ax,32768 ; copy all 32k
xor dx,dx ; DX:AX = 32768
lea si,xoffset ; start at offset 0 in memory block
call xget ; copy the graph back to video buffer
jc xerror
; all done with graph copy; release the memory block
call xfree
jc xerror